home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / djgpp / src / gas-211 / gas / config / obj-elf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-30  |  30.4 KB  |  1,192 lines

  1. /* ELF object file format
  2.    Copyright (C) 1992, 1993 Free Software Foundation, Inc.
  3.  
  4.    This file is part of GAS, the GNU Assembler.
  5.  
  6.    GAS is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as
  8.    published by the Free Software Foundation; either version 2,
  9.    or (at your option) any later version.
  10.  
  11.    GAS is distributed in the hope that it will be useful, but
  12.    WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  14.    the GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public
  17.    License along with GAS; see the file COPYING.  If not, write
  18.    to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  19.  
  20. /* HP PA-RISC support was contributed by the Center for Software Science
  21.    at the University of Utah.  */
  22.  
  23. #include "as.h"
  24. #include "aout/stab_gnu.h"
  25. #include "obstack.h"
  26.  
  27. static void obj_elf_stab PARAMS ((int what));
  28. static void obj_elf_line PARAMS ((void));
  29. static void obj_elf_desc PARAMS ((void));
  30. static void obj_elf_version PARAMS ((void));
  31. static void obj_elf_section PARAMS ((int));
  32. static void obj_elf_size PARAMS ((void));
  33. static void obj_elf_type PARAMS ((void));
  34. static void obj_elf_ident PARAMS ((void));
  35.  
  36. const pseudo_typeS obj_pseudo_table[] = {
  37.   { "ident",    obj_elf_ident,        0 },
  38.   { "section",    obj_elf_section,    0 },
  39.   { "size",    obj_elf_size,        0 },
  40.   { "type",    obj_elf_type,        0 },
  41.   { "version",  obj_elf_version,    0 },
  42.  
  43.   /* These are used for stabs-in-elf configurations.  */
  44.   { "desc",    obj_elf_desc,        0    },
  45.   { "line",    obj_elf_line,        0    },
  46.   { "stabd",    obj_elf_stab,        'd'    },
  47.   { "stabn",    obj_elf_stab,        'n'    },
  48.   { "stabs",    obj_elf_stab,        's'    },
  49.   /* This is used on Solaris 2.x on SPARC, but not supported yet.  */
  50.   { "xstabs",    s_ignore,        0    },
  51.  
  52.   { NULL}    /* end sentinel */
  53. };
  54.  
  55. static void
  56. obj_elf_section (xxx)
  57.      int xxx;
  58. {
  59.   char *string;
  60.   asection *sec;
  61.  
  62.   /* Initialize this with inclusive-or of all flags that can be cleared
  63.      by attributes, but not set by them.  Also include flags that won't
  64.      get set properly in the assembler, but which the user/compiler
  65.      shouldn't be expected to set.  */
  66.   flagword flags = SEC_READONLY | SEC_ALLOC | SEC_RELOC;
  67.   /* Initialize this with the default flags to be used if none are
  68.      specified.  */
  69.   flagword default_flags = SEC_ALLOC | SEC_RELOC;
  70.  
  71.   string = demand_copy_C_string (&xxx);
  72.   SKIP_WHITESPACE ();
  73.   if (*input_line_pointer != ',')
  74.     flags = default_flags;
  75.   while (*input_line_pointer == ',')
  76.     {
  77.       flagword bit;
  78.       int len, inv;
  79.       char *p, oldp;
  80.  
  81.       input_line_pointer++;
  82.       if (*input_line_pointer != '#')
  83.     {
  84.       as_bad ("unrecognized syntax in .section command");
  85.       ignore_rest_of_line ();
  86.       break;
  87.     }
  88.       input_line_pointer++;
  89.  
  90. #define CHECK(X,BIT,NEG)    \
  91.       if (!strncmp(X,input_line_pointer,len = sizeof(X) - 1)) { \
  92.     bit = BIT; inv = NEG; goto match; }
  93.  
  94.       CHECK ("write", SEC_READONLY, 1);
  95.       CHECK ("alloc", SEC_ALLOC, 0);
  96. #undef CHECK
  97.  
  98.       p = input_line_pointer;
  99.       while (!is_end_of_line[*p] && *p != 0 && *p != ',')
  100.     p++;
  101.       *p = 0;
  102.       oldp = *p;
  103.       as_bad ("unrecognized section attribute `%s' ignored",
  104.           input_line_pointer);
  105.       *p = oldp;
  106.       continue;
  107.  
  108.     match:
  109.       if (inv)
  110.     flags &= ~bit;
  111.       else
  112.     flags |= bit;
  113.       input_line_pointer += len;
  114.     }
  115.   demand_empty_rest_of_line ();
  116.  
  117.   sec = bfd_get_section_by_name (stdoutput, string);
  118.   if (sec == 0)
  119.     {
  120.       sec = bfd_make_section_old_way (stdoutput, string);
  121.       bfd_set_section_flags (stdoutput, sec,
  122.                  /* @@ What should the flags be??  */
  123.                  flags);
  124.       sec->output_section = sec;
  125.     }
  126.   subseg_change (sec, 0);
  127. }
  128.  
  129. #if 0
  130. /* pa-spaces.c -- Space/subspace support for the HP PA-RISC version of GAS */
  131.  
  132. /* for space, subspace, and symbol maintenance on HP 9000 Series 800 */
  133.  
  134. space_dict_chainS *space_dict_root;
  135. space_dict_chainS *space_dict_last;
  136.  
  137. space_dict_chainS *current_space;
  138. subspace_dict_chainS *current_subspace;
  139. #endif
  140.  
  141. symbolS *start_symbol_root;
  142. symbolS *start_symbol_last;
  143.  
  144. #if 0 /* I really don't think this belongs in this file.  */
  145. void pa_spaces_begin()
  146. {
  147.   space_dict_chainS *space;
  148.   int i;
  149.   subsegT now_subseg    = now_subseg;
  150.  
  151.   space_dict_root = NULL;
  152.   space_dict_last = NULL;
  153.  
  154.   start_symbol_root = NULL;
  155.   start_symbol_last = NULL;
  156.  
  157.   /* create default space and subspace dictionaries */
  158.  
  159.   i = 0;
  160.   while ( pa_def_spaces[i].name ) {
  161.       if ( pa_def_spaces[i].alias )
  162.           pa_def_spaces[i].segment = subseg_new(pa_def_spaces[i].alias,0);
  163.       else
  164.           pa_def_spaces[i].segment = bfd_make_section_old_way(stdoutput,pa_def_spaces[i].name);
  165.  
  166.       create_new_space(pa_def_spaces[i].name,pa_def_spaces[i].spnum,
  167.                pa_def_spaces[i].loadable,pa_def_spaces[i].defined,
  168.                pa_def_spaces[i].private,pa_def_spaces[i].sort,0,
  169.                pa_def_spaces[i].segment);
  170.       i++;
  171.   }
  172.  
  173.   i = 0;
  174.   while ( pa_def_subspaces[i].name ) {
  175.       space = pa_segment_to_space(pa_def_spaces[pa_def_subspaces[i].def_space_index].segment);
  176.       if ( space ) {
  177.           create_new_subspace(space,
  178.                       pa_def_subspaces[i].name,pa_def_subspaces[i].defined,
  179.                       pa_def_subspaces[i].loadable,
  180.                       pa_def_subspaces[i].code_only,pa_def_subspaces[i].common,
  181.                       pa_def_subspaces[i].dup_common,pa_def_subspaces[i].zero,
  182.                       pa_def_subspaces[i].sort,pa_def_subspaces[i].access,
  183.                       pa_def_subspaces[i].space_index,
  184.                       pa_def_subspaces[i].alignment,
  185.                       pa_def_subspaces[i].quadrant,
  186.                       pa_def_spaces[pa_def_subspaces[i].def_space_index].segment);
  187.           subseg_new(pa_def_subspaces[i].name,pa_def_subspaces[i].subsegment);
  188.       }
  189.       else
  190.           as_fatal("Internal error: space missing for subspace \"%s\"\n",
  191.                pa_def_subspaces[i].name);
  192.       i++;
  193.   }
  194. }
  195.  
  196. space_dict_chainS *create_new_space(name,spnum,loadable,defined,private,sort,defined_in_file,seg)
  197.      char *name;
  198.      int spnum;
  199.      char loadable;
  200.      char defined;
  201.      char private;
  202.      char sort;
  203.      char defined_in_file;
  204.      asection * seg;
  205.  
  206. {
  207.   Elf_Internal_Shdr *new_space;
  208.   space_dict_chainS *chain_entry;
  209.  
  210.   new_space = (Elf_Internal_Shdr *)xmalloc(sizeof(Elf_Internal_Shdr));
  211.   if ( !new_space )
  212.     as_fatal("Out of memory: could not allocate new Elf_Internal_Shdr: %s\n",name);
  213.  
  214.   /*
  215.   new_space->space_number = spnum;
  216.   new_space->is_loadable = loadable & 1;
  217.   new_space->is_defined = defined & 1;
  218.   new_space->is_private = private & 1;
  219.   new_space->sort_key = sort & 0xff;
  220.  
  221.   new_space->loader_fix_index = ~0;
  222.   new_space->loader_fix_quantity = 0;
  223.   new_space->init_pointer_index = ~0;
  224.   new_space->init_pointer_quantity = 0;
  225.   new_space->subspace_quantity = 0;
  226.   */
  227.  
  228.   chain_entry = (space_dict_chainS *)xmalloc(sizeof(space_dict_chainS));
  229.   if ( !chain_entry )
  230.     as_fatal("Out of memory: could not allocate new space chain entry: %s\n",name);
  231.  
  232.   SPACE_NAME(chain_entry) = (char *)xmalloc(strlen(name)+1);
  233.   strcpy(SPACE_NAME(chain_entry),name);
  234.  
  235.   chain_entry->sd_entry = new_space;
  236.   chain_entry->sd_defined = defined_in_file;
  237.   chain_entry->sd_seg = seg;
  238.   chain_entry->sd_last_subseg = -1;
  239.   chain_entry->sd_next = NULL;
  240.  
  241.   SPACE_SPNUM(chain_entry) = spnum;
  242.   SPACE_LOADABLE(chain_entry) = loadable & 1;
  243.   SPACE_DEFINED(chain_entry) = defined & 1;
  244.   SPACE_PRIVATE(chain_entry) = private & 1;
  245.   SPACE_SORT(chain_entry) = sort & 0xff;
  246.  
  247.   /* find spot for the new space based on its sort key */
  248.  
  249.   if ( !space_dict_last )
  250.     space_dict_last = chain_entry;
  251.  
  252.   if ( space_dict_root == NULL )        /* if root is null, it is very easy */
  253.     space_dict_root = chain_entry;
  254.   else
  255.     {
  256.       space_dict_chainS *sdcP;
  257.       space_dict_chainS *last_sdcP;
  258.  
  259.       sdcP = space_dict_root;
  260.       last_sdcP = NULL;
  261.  
  262.       while ( sdcP ) {
  263.     if ( SPACE_SORT(sdcP) < SPACE_SORT(chain_entry) ) {
  264.       last_sdcP = sdcP;
  265.       sdcP = sdcP->sd_next;
  266.     }
  267.     else if ( SPACE_SORT(sdcP) == SPACE_SORT(chain_entry) ) {
  268.       last_sdcP = sdcP;
  269.       sdcP = sdcP->sd_next;
  270.     }
  271.     else if ( SPACE_SORT(sdcP) > SPACE_SORT(chain_entry) ) {
  272.       break;
  273.     }    
  274.       }
  275.  
  276.       if ( last_sdcP ) {
  277.     chain_entry->sd_next = sdcP;
  278.     last_sdcP->sd_next = chain_entry;
  279.       }
  280.       else {
  281.     space_dict_root = chain_entry;
  282.     chain_entry->sd_next = sdcP;
  283.       }
  284.  
  285.       if ( chain_entry->sd_next  == NULL )
  286.     space_dict_last = chain_entry;
  287.     }
  288.  
  289.   return chain_entry;
  290. }
  291.  
  292. subspace_dict_chainS
  293. *create_new_subspace(space,name,defined,loadable,code_only,common,dup_common,
  294.              is_zero,sort,access,space_index,alignment,quadrant,seg)
  295.      space_dict_chainS *space;
  296.      char *name;
  297.      char defined,loadable,code_only,common,dup_common,is_zero;
  298.      char sort;
  299.      int access;
  300.      int space_index;
  301.      int alignment;
  302.      int quadrant;
  303.      asection * seg;
  304. {
  305.   Elf_Internal_Shdr * new_subspace;
  306.   subspace_dict_chainS * chain_entry;
  307.   symbolS * start_symbol;
  308.  
  309.   new_subspace = (Elf_Internal_Shdr *)xmalloc(sizeof(Elf_Internal_Shdr));
  310.   if ( !new_subspace )
  311.     as_fatal("Out of memory: could not allocate new Elf_Internal_Shdr: %s\n",
  312.         name);
  313.  
  314.   /*
  315.   new_subspace->space_index = space_index;
  316.   new_subspace->fixup_request_index = ~0;
  317.   */
  318.  
  319.   chain_entry = (subspace_dict_chainS *)xmalloc(sizeof(subspace_dict_chainS));
  320.   if ( !chain_entry )
  321.     as_fatal("Out of memory: could not allocate new subspace chain entry: %s\n",name);
  322.  
  323.   chain_entry->ssd_entry = new_subspace;
  324.   SUBSPACE_NAME(chain_entry) = (char *)xmalloc(strlen(name)+1);
  325.   strcpy(SUBSPACE_NAME(chain_entry),name);
  326.  
  327.   SUBSPACE_ACCESS(chain_entry) = access & 0x7f;
  328.   SUBSPACE_LOADABLE(chain_entry) = loadable & 1;
  329.   SUBSPACE_COMMON(chain_entry) = common & 1;
  330.   SUBSPACE_DUP_COMM(chain_entry) = dup_common & 1;
  331.   SUBSPACE_SORT(chain_entry) = sort & 0xff;
  332.   SET_SUBSPACE_CODE_ONLY(chain_entry,code_only & 1);
  333.   SUBSPACE_ALIGN(chain_entry) = alignment & 0xffff;
  334.   SUBSPACE_QUADRANT(chain_entry) = quadrant & 0x3;
  335.   SUBSPACE_SUBSPACE_START(chain_entry) = pa_subspace_start(space,quadrant);
  336.  
  337.   chain_entry->ssd_defined = defined;
  338.   chain_entry->ssd_space_number = space_index;
  339.   chain_entry->ssd_subseg = pa_next_subseg(space);
  340.   chain_entry->ssd_seg = seg;
  341.   SUBSPACE_ZERO(chain_entry) = is_zero;
  342.   chain_entry->ssd_last_align = 1;
  343.   chain_entry->ssd_next = NULL;
  344.  
  345.   /* find spot for the new subspace based on its sort key */
  346.  
  347.   if ( space->sd_subspaces == NULL )        /* if root is null, it is very easy */
  348.     space->sd_subspaces = chain_entry;
  349.   else
  350.     {
  351.       subspace_dict_chainS *ssdcP;
  352.       subspace_dict_chainS *last_ssdcP;
  353.  
  354.       ssdcP = space->sd_subspaces;
  355.       last_ssdcP = NULL;
  356.  
  357.       while ( ssdcP ) {
  358.     if ( SUBSPACE_SORT(ssdcP) < SUBSPACE_SORT(chain_entry) ) {
  359.       last_ssdcP = ssdcP;
  360.       ssdcP = ssdcP->ssd_next;
  361.     }
  362.     else if ( SUBSPACE_SORT(ssdcP) == SUBSPACE_SORT(chain_entry) ) {
  363.       last_ssdcP = ssdcP;
  364.       ssdcP = ssdcP->ssd_next;
  365.     }
  366.     else if ( SUBSPACE_SORT(ssdcP) > SUBSPACE_SORT(chain_entry) ) {
  367.       break;
  368.     }    
  369.       }
  370.  
  371.       if ( last_ssdcP ) {
  372.     chain_entry->ssd_next = ssdcP;
  373.     last_ssdcP->ssd_next = chain_entry;
  374.       }
  375.       else {
  376.     space->sd_subspaces = chain_entry;
  377.     chain_entry->ssd_next = ssdcP;
  378.       }
  379.     }
  380.  
  381.   start_symbol = pa_set_start_symbol(seg,space->sd_last_subseg);
  382.   chain_entry->ssd_start_sym = start_symbol;
  383.   return chain_entry;
  384.  
  385. }
  386.  
  387. subspace_dict_chainS
  388. *update_subspace(name,defined,loadable,code_only,common,dup_common,sort,zero,
  389.          access,space_index,alignment,quadrant,subseg)
  390.      char *name;
  391.      char defined,loadable,code_only,common,dup_common,zero;
  392.      char sort;
  393.      int access;
  394.      int space_index;
  395.      int alignment;
  396.      int quadrant;
  397.      subsegT subseg;
  398. {
  399.   subspace_dict_chainS *chain_entry;
  400.   subspace_dict_chainS *is_defined_subspace();
  401.  
  402.   if ( (chain_entry = is_defined_subspace(name,subseg)) ) {
  403.  
  404.     SUBSPACE_ACCESS(chain_entry) = access & 0x7f;
  405.     SUBSPACE_LOADABLE(chain_entry) = loadable & 1;
  406.     SUBSPACE_COMMON(chain_entry) = common & 1;
  407.     SUBSPACE_DUP_COMM(chain_entry) = dup_common & 1;
  408.     SET_SUBSPACE_CODE_ONLY(chain_entry,code_only & 1);
  409.     SUBSPACE_SORT(chain_entry) = sort & 0xff;
  410.     /* chain_entry->ssd_entry->space_index = space_index; */
  411.     SUBSPACE_ALIGN(chain_entry) = alignment & 0xffff;
  412.     SUBSPACE_QUADRANT(chain_entry) = quadrant & 0x3;
  413.  
  414.     chain_entry->ssd_defined = defined;
  415.     chain_entry->ssd_space_number = space_index;
  416.     SUBSPACE_ZERO(chain_entry) = zero;
  417.   }
  418.   else
  419.     chain_entry = NULL;
  420.  
  421.   return chain_entry;
  422.  
  423. }
  424.  
  425. space_dict_chainS *is_defined_space(name)
  426.      char *name;
  427. {
  428.   space_dict_chainS *spaceCh;
  429.  
  430.   for (spaceCh = space_dict_root;spaceCh;spaceCh=spaceCh->sd_next ) {
  431.     if ( strcmp(SPACE_NAME(spaceCh),name) == 0 ) {
  432.       return spaceCh;
  433.     }
  434.   }
  435.  
  436.   return NULL;
  437. }
  438.  
  439. space_dict_chainS *pa_segment_to_space(seg)
  440.      asection * seg;
  441. {
  442.   space_dict_chainS *spaceCh;
  443.  
  444.   for (spaceCh = space_dict_root;spaceCh;spaceCh=spaceCh->sd_next ) {
  445.     if ( spaceCh->sd_seg == seg ) {
  446.       return spaceCh;
  447.     }
  448.   }
  449.  
  450.   return NULL;
  451. }
  452.  
  453. subspace_dict_chainS *is_defined_subspace(name,subseg)
  454.      char *name;
  455.      subsegT subseg;
  456. {
  457.   space_dict_chainS *spaceCh;
  458.   subspace_dict_chainS *subspCh;
  459.  
  460.   for ( spaceCh = space_dict_root; spaceCh; spaceCh = spaceCh->sd_next ) {
  461.     for ( subspCh = spaceCh->sd_subspaces; subspCh; subspCh=subspCh->ssd_next ) {
  462.       /*
  463.     if ( strcmp(SUBSPACE_NAME(subspCh),name) == 0 &&
  464.         subspCh->ssd_subseg == subseg ) {
  465.        */
  466.     if ( strcmp(SUBSPACE_NAME(subspCh),name) == 0 ) {
  467.       return subspCh;
  468.     }
  469.     }
  470.   }
  471.   return NULL;
  472. }
  473.  
  474. subspace_dict_chainS *pa_subsegment_to_subspace(seg,subseg)
  475.     asection * seg;
  476.     subsegT subseg;
  477. {
  478.   space_dict_chainS *spaceCh;
  479.   subspace_dict_chainS *subspCh;
  480.  
  481.   for ( spaceCh = space_dict_root; spaceCh; spaceCh = spaceCh->sd_next ) {
  482.     if ( spaceCh->sd_seg == seg ) {
  483.       for (subspCh = spaceCh->sd_subspaces;subspCh;subspCh=subspCh->ssd_next ) {
  484.     if ( subspCh->ssd_subseg == (int)subseg ) {
  485.       return subspCh;
  486.     }
  487.       }
  488.     }
  489.   }
  490.  
  491.   return NULL;
  492. }
  493.  
  494. space_dict_chainS *pa_find_space_by_number(number)
  495.      int number;
  496. {
  497.   space_dict_chainS *spaceCh;
  498.  
  499.   for (spaceCh = space_dict_root;spaceCh;spaceCh=spaceCh->sd_next ) {
  500.     if ( SPACE_SPNUM(spaceCh) == number ) {
  501.       return spaceCh;
  502.     }
  503.   }
  504.  
  505.   return NULL;
  506. }
  507.  
  508. unsigned int pa_subspace_start(space,quadrant)
  509.      space_dict_chainS *space;
  510.      int quadrant;
  511. {
  512.   if ( (strcasecmp(SPACE_NAME(space),"$PRIVATE$") == 0) &&
  513.        quadrant == 1 ) {
  514.     return 0x40000000;
  515.   }
  516.   else if ( space->sd_seg == data_section && quadrant == 1 ) {  /* in case name is */
  517.                                                             /* already converted */
  518.                                                             /* to a space dict- */
  519.                                                             /* ionary index */
  520.     return 0x40000000;
  521.   }
  522.   else
  523.     return 0;
  524. }
  525.  
  526. int pa_next_subseg(space)
  527.      space_dict_chainS *space;
  528. {
  529.  
  530.   space->sd_last_subseg++;
  531.   return space->sd_last_subseg;
  532. }
  533.  
  534. int is_last_defined_subspace(ssd)
  535.      subspace_dict_chainS *ssd;
  536. {
  537.  
  538.   for ( ;ssd; ssd = ssd->ssd_next ) {
  539.     if ( ssd->ssd_defined )
  540.       return FALSE;
  541.   }
  542.  
  543.   return TRUE;
  544. }
  545.  
  546. symbolS *pa_get_start_symbol(seg,subseg)
  547.      asection * seg;
  548.      subsegT subseg;
  549. {
  550.   symbolS *start_symbol;
  551.   subspace_dict_chainS *ssd;
  552.  
  553.   start_symbol = NULL;
  554.  
  555.   /* each time a new space is created, build a symbol called LS$START_seg_subseg$ */
  556.   /* where <space-name> is the name of the space */
  557.   /* the start symbol will be SS_LOCAL and ST_CODE */
  558.  
  559.   if ( seg == bfd_make_section_old_way ( stdoutput, ".text" ) ||
  560.        seg == bfd_make_section_old_way ( stdoutput, ".data" ) ||
  561.        seg == bfd_make_section_old_way ( stdoutput, GDB_DEBUG_SPACE_NAME ) ) {
  562.       ssd = pa_subsegment_to_subspace(seg,subseg);
  563.       if ( ssd ) {
  564.           start_symbol = ssd->ssd_start_sym;
  565.       }
  566.       else
  567.           as_fatal("Internal error: missing subspace for (seg,subseg)=('%s',%d)",
  568.                seg->name,subseg);
  569.   }
  570.   else
  571.       as_fatal("Internal error: attempt to find start symbol for unloadable segment: '%s'",
  572.            seg->name);
  573.  
  574.   return start_symbol;
  575. }
  576.  
  577. /*
  578.   Function to define a symbol whose address is the beginning of a subspace.
  579.   This function assumes the symbol is to be defined for the current subspace.
  580.  */
  581.  
  582. symbolS *pa_set_start_symbol(seg,subseg)
  583.      asection * seg;
  584.      subsegT subseg;
  585. {
  586.   symbolS *start_symbol;
  587.   subspace_dict_chainS *ssd;
  588.   char *symbol_name;
  589.  
  590.   symbol_name = (char *)xmalloc(strlen("LS$START__000000$")+strlen(seg->name)+1);
  591.  
  592.   sprintf(symbol_name,"LS$START_%s_%03d$",seg->name,subseg);
  593.  
  594.   start_symbol
  595.       = symbol_new(symbol_name,seg,0,frag_now); /* XXX: not sure if value s.b. 0 or frag s.b. NULL */
  596.  
  597.   start_symbol->bsym->flags    = BSF_LOCAL;    /* XXX: isn't there a macro defined for this? */
  598.  
  599.   /* each time a new space is created, build a symbol called LS$START_seg_subseg$ */
  600.   /* where <space-name> is the name of the space */
  601.   /* the start symbol will be SS_LOCAL and ST_CODE */
  602.   /* This function assumes that (seg,subseg) is a new subsegment(subspace) */
  603.  
  604.   if ( seg == bfd_make_section_old_way ( stdoutput, ".text" ) ||
  605.        seg == bfd_make_section_old_way ( stdoutput, ".data" ) ||
  606.        seg == bfd_make_section_old_way ( stdoutput, GDB_DEBUG_SPACE_NAME ) ) {
  607.       ssd = pa_subsegment_to_subspace(seg,subseg);
  608.       if ( ssd ) {
  609.           ssd->ssd_start_sym = start_symbol;
  610.       }
  611.       else
  612.           as_fatal("Internal error: missing subspace for (seg,subseg)=('%s',%d)",
  613.                seg,subseg);
  614.   }
  615.   else
  616.       as_fatal("Internal error: attempt to define start symbol for unloadable segment: '%s'",
  617.            seg->name);
  618.  
  619.   return start_symbol;
  620. }
  621. #endif
  622.  
  623. int
  624. obj_elf_frob_symbol (sym, punt)
  625.      symbolS *sym;
  626.      int *punt;
  627. {
  628.  
  629.     /* If this is a local symbol, are there any relocations for */
  630.     /* which need this symbol?    */
  631.  
  632.     /* To find this out, we examine all relocations    in all bfd */
  633.     /* sections that have relocations.  If there is one that */
  634.     /* references this symbol, we need to keep this symbol.  In */
  635.     /* this case, we return a true status.  In all other cases, we */
  636.     /* return a false status.    */
  637.  
  638.     if ( S_IS_LOCAL(sym) ) {
  639.         asymbol *bsym = sym->bsym;    
  640.         bfd *abfd = bsym->the_bfd;
  641.         asection *bsec;
  642.  
  643.         for ( bsec = abfd->sections; bsec; bsec = bsec->next ) {
  644.             struct reloc_cache_entry **rlocs = bsec->orelocation;
  645.             int rcnt = bsec->reloc_count;
  646.  
  647.             if ( rlocs ) {
  648.                 int i;
  649.  
  650.                 for ( i = 0; i < rcnt; i++ ) {
  651.                     if ( rlocs[i]->sym_ptr_ptr
  652.                         && rlocs[i]->sym_ptr_ptr[0] == bsym )
  653.                         return 1;
  654.                 }
  655.             }
  656.         }
  657.     }
  658.     return 0;
  659. }
  660.  
  661. static void obj_elf_line() {
  662.     /* Assume delimiter is part of expression.
  663.        BSD4.2 as fails with delightful bug, so we
  664.        are not being incompatible here. */
  665.     new_logical_line((char *)NULL, (int)(get_absolute_expression()));
  666.     demand_empty_rest_of_line();
  667. } /* obj_elf_line() */
  668.  
  669. /*
  670.  *            stab()
  671.  *
  672.  * Handle .stabX directives, which used to be open-coded.
  673.  * So much creeping featurism overloaded the semantics that we decided
  674.  * to put all .stabX thinking in one place. Here.
  675.  *
  676.  * We try to make any .stabX directive legal. Other people's AS will often
  677.  * do assembly-time consistency checks: eg assigning meaning to n_type bits
  678.  * and "protecting" you from setting them to certain values. (They also zero
  679.  * certain bits before emitting symbols. Tut tut.)
  680.  *
  681.  * If an expression is not absolute we either gripe or use the relocation
  682.  * information. Other people's assemblers silently forget information they
  683.  * don't need and invent information they need that you didn't supply.
  684.  *
  685.  * .stabX directives always make a symbol table entry. It may be junk if
  686.  * the rest of your .stabX directive is malformed.
  687.  */
  688.  
  689. /*
  690.  *                      pa_stab_symbol_string()
  691.  *
  692.  * Build a string dictionary entry for a .stabX symbol.
  693.  * The symbol is added to the .stabstr section.
  694.  *
  695.  */
  696.  
  697. static unsigned int gdb_string_index = 0;
  698.  
  699. static unsigned int
  700. elf_stab_symbol_string(string)
  701.      char *string;
  702. {
  703.   asection *save_seg;
  704.   asection *seg;
  705.   subsegT save_subseg;
  706.   unsigned int length;
  707.   unsigned int old_gdb_string_index;
  708.   char *clengthP;
  709.   int i;
  710.   char c;
  711.  
  712.   old_gdb_string_index = 0;
  713.   length = strlen(string);
  714.   clengthP = (char *)&length;
  715.   if ( length > 0 ) {            /* Ordinary case. */
  716.     save_seg = now_seg;
  717.     save_subseg = now_subseg;
  718.  
  719.     /* Create the stab sections, if they are not already created. */
  720.     seg = bfd_get_section_by_name(stdoutput,".stabstr");
  721.     if ( seg == 0 ) {
  722.         seg = bfd_make_section_old_way(stdoutput,".stabstr");
  723.         bfd_set_section_flags (stdoutput,
  724.                    seg,
  725.                    SEC_READONLY | SEC_ALLOC | SEC_LOAD );
  726.     }
  727.     subseg_new(seg->name,save_subseg);
  728.     old_gdb_string_index = gdb_string_index;
  729.     i = 0;
  730.     while ( (c = *string++) )
  731.       {
  732.     i++;
  733.         gdb_string_index++;
  734.     FRAG_APPEND_1_CHAR( c );
  735.       }
  736.     {
  737.       FRAG_APPEND_1_CHAR( (char)0 );
  738.       i++;
  739.       gdb_string_index++;
  740.     }
  741.     while ( i%4 != 0 ) {
  742.       FRAG_APPEND_1_CHAR( (char)0 );
  743.       i++;
  744.       gdb_string_index++;
  745.     }
  746.     subseg_new(save_seg->name,save_subseg);
  747.   }
  748.  
  749.   return old_gdb_string_index;
  750. }
  751.  
  752. unsigned int
  753. elf_stab_symbol(symbolP,stab_type)
  754.      symbolS *symbolP;
  755.      int stab_type;
  756. {
  757.   unsigned int length;
  758.   int i;
  759.   char c;
  760.   char *toP;
  761.  
  762.   /* the string index portion of the stab */
  763.  
  764.   toP = frag_more( sizeof(long) +
  765.            sizeof(S_GET_TYPE(symbolP)) +
  766.            sizeof(S_GET_OTHER(symbolP)) +
  767.            sizeof(S_GET_DESC(symbolP)));
  768.   md_number_to_chars(toP,symbolP->sy_name_offset,sizeof(long));
  769.   md_number_to_chars(toP,
  770.              S_GET_TYPE(symbolP),
  771.              sizeof(S_GET_TYPE(symbolP)));
  772.   md_number_to_chars(toP + sizeof(S_GET_TYPE(symbolP)),
  773.              S_GET_OTHER(symbolP),
  774.              sizeof(S_GET_OTHER(symbolP)));
  775.   md_number_to_chars(toP + sizeof(S_GET_TYPE(symbolP))
  776.                  + sizeof(S_GET_OTHER(symbolP)),
  777.              S_GET_DESC(symbolP),
  778.              sizeof(S_GET_DESC(symbolP)));
  779.  
  780.   /* n_value has to be relocated */
  781.  
  782.   /* Don't bother relocating if we're only adding in a constant. */
  783.  
  784.   if ((stab_type == 's' || stab_type == 'n') && symbolP->sy_forward == 0)
  785.       S_SET_VALUE(symbolP,S_GET_VALUE(symbolP->sy_forward));
  786.  
  787.   toP = frag_more(4);
  788.   md_number_to_chars(toP, S_GET_VALUE(symbolP),
  789.              sizeof(S_GET_VALUE(symbolP)));
  790.  
  791. #if 0
  792.   if ( (stab_type == 's' || stab_type == 'n') && symbolP->sy_forward )
  793.     {
  794.       i = S_GET_TYPE(symbolP) & N_TYPE;
  795.       fix_new_hppa(frag_now,    /* which frag */
  796.            toP-frag_now->fr_literal, /* where */
  797.            4,        /* size */
  798.            symbolP->sy_forward,    /* addr of symbol for this stab */
  799.            (asymbol *)NULL,
  800.            0,
  801.            i == N_UNDF || i == N_ABS,    /* 1 if internal relocation */
  802.            R_HPPA,    /* reloc type */
  803.            e_fsel,    /* fixup field = F% */
  804.            32,
  805.            0,        /* arg_reloc descriptor */
  806.            (char *)0
  807.            );
  808.     }
  809.   else if ( stab_type == 'd' )
  810.     {
  811.       fix_new_hppa (frag_now,    /* which frag */
  812.             toP-frag_now->fr_literal, /* where */
  813.             4,        /* size */
  814.             symbolP,    /* addr of symbol for this stab */
  815.             (asymbol *)NULL,
  816.             0,
  817.             0,
  818.             R_HPPA,    /* reloc type */
  819.             e_fsel,    /* fixup field = F% */
  820.             32,
  821.             0,        /* arg_reloc descriptor */
  822.             (char *)0
  823.             );
  824.     }
  825. #else
  826.   /* What needs to replace the above code?  */
  827.   abort ();
  828. #endif
  829. }
  830.  
  831. static void obj_elf_stab(what)
  832.      int what;
  833. {
  834.   extern int listing;
  835.  
  836.   symbolS *    symbolP = 0;
  837.   char *    string;
  838.   int saved_type = 0;
  839.   int length;
  840.   int goof = 0;
  841.   long longint;
  842.   asection *saved_seg = now_seg;
  843.   asection *seg;
  844.   subsegT subseg = now_subseg;
  845.  
  846.   seg = bfd_get_section_by_name(stdoutput,".stab");
  847.   if ( seg == 0 )
  848.     {
  849.       seg = bfd_make_section_old_way(stdoutput,".stab");
  850.       bfd_set_section_flags (stdoutput,
  851.                  seg,
  852.                  SEC_READONLY | SEC_ALLOC | SEC_LOAD | SEC_RELOC);
  853.     }
  854.  
  855.   /*
  856.    * Enter with input_line_pointer pointing past .stabX and any following
  857.    * whitespace.
  858.    */
  859.   if (what == 's') {
  860.       string = demand_copy_C_string(& length);
  861.       SKIP_WHITESPACE();
  862.       if (* input_line_pointer == ',')
  863.        input_line_pointer ++;
  864.       else
  865.     {
  866.       as_bad("I need a comma after symbol's name");
  867.       goof = 1;
  868.     }
  869.     }
  870.   else
  871.     string = "";
  872.  
  873.   /*
  874.    * Input_line_pointer->after ','.  String->symbol name.
  875.    */
  876.   if (! goof)
  877.     {
  878.       symbolP = symbol_new(string, &bfd_und_section, 0, (struct frag *)0);
  879.  
  880.       /* enter the string in the .stab string table (section .stabstr) */
  881.       symbolP->sy_name_offset = elf_stab_symbol_string(string);
  882.  
  883.       switch (what)
  884.     {
  885.     case 'd':
  886.       S_SET_NAME(symbolP, NULL); /* .stabd feature. */
  887.       S_SET_VALUE(symbolP, obstack_next_free(&frags) - frag_now->fr_literal);
  888.       S_SET_SEGMENT(symbolP, now_seg);
  889.       symbolP->sy_frag = frag_now;
  890.       break;
  891.  
  892.     case 'n':
  893.       symbolP->sy_frag = &zero_address_frag;
  894.       break;
  895.  
  896.     case 's':
  897.       symbolP->sy_frag = & zero_address_frag;
  898.       break;
  899.  
  900.     default:
  901.       BAD_CASE(what);
  902.       break;
  903.     }
  904.  
  905.       if (get_absolute_expression_and_terminator(&longint) == ',')
  906.     {
  907.       saved_type = longint;
  908.       S_SET_TYPE (symbolP, saved_type);
  909.     }
  910.       else
  911.     {
  912.       as_bad("I want a comma after the n_type expression");
  913.       goof = 1;
  914.       input_line_pointer --; /* Backup over a non-',' char. */
  915.     }
  916.     }
  917.  
  918.   if (!goof)
  919.     {
  920.       if (get_absolute_expression_and_terminator(&longint) == ',')
  921.     S_SET_OTHER(symbolP, longint);
  922.       else
  923.     {
  924.       as_bad("I want a comma after the n_other expression");
  925.       goof = 1;
  926.       input_line_pointer--; /* Backup over a non-',' char. */
  927.     }
  928.     }
  929.  
  930.   if (!goof)
  931.     {
  932.       S_SET_DESC(symbolP, get_absolute_expression());
  933.       if (what == 's' || what == 'n')
  934.     {
  935.       if (*input_line_pointer != ',')
  936.         {
  937.           as_bad("I want a comma after the n_desc expression");
  938.           goof = 1;
  939.         }
  940.       else
  941.         {
  942.           input_line_pointer++;
  943.         }
  944.     }
  945.     }
  946.  
  947.   if ( !goof ) {
  948.       if ( what=='s' || what=='n' ) {
  949.           pseudo_set(symbolP);
  950.           S_SET_TYPE (symbolP, saved_type);
  951.       }
  952.       /* Emit the stab symbol. */
  953.       subseg_new(seg->name,subseg);
  954.       elf_stab_symbol(symbolP, what);
  955.       subseg_new(saved_seg->name,subseg);
  956.  
  957.       if ( what=='s' || what=='n' && symbolP->sy_forward == NULL ) {
  958.           /* symbol is not needed in the regular symbol table */
  959.           symbol_remove(symbolP,&symbol_rootP,&symbol_lastP);
  960.       }
  961.  
  962.   }
  963.  
  964. #ifndef NO_LISTING
  965.   if (listing && !goof)
  966.     switch (S_GET_TYPE (symbolP))
  967.       {
  968.       case N_SLINE:
  969.     listing_source_line (S_GET_DESC (symbolP));
  970.     break;
  971.       case N_SO:
  972.       case N_SOL:
  973.     listing_source_file (string);
  974.     break;
  975.       }
  976. #endif
  977.  
  978.   if (goof)
  979.     ignore_rest_of_line();
  980.   else
  981.     demand_empty_rest_of_line ();
  982. } /* obj_elf_stab() */
  983.  
  984. static void obj_elf_desc() {
  985.     char *name;
  986.     char c;
  987.     char *p;
  988.     symbolS *symbolP;
  989.     int temp;
  990.     
  991.     /*
  992.      * Frob invented at RMS' request. Set the n_desc of a symbol.
  993.      */
  994.     name = input_line_pointer;
  995.     c = get_symbol_end();
  996.     p = input_line_pointer;
  997.     * p = c;
  998.     SKIP_WHITESPACE();
  999.     if (*input_line_pointer != ',') {
  1000.         *p = 0;
  1001.         as_bad("Expected comma after name \"%s\"", name);
  1002.         *p = c;
  1003.         ignore_rest_of_line();
  1004.     } else {
  1005.         input_line_pointer ++;
  1006.         temp = get_absolute_expression();
  1007.         *p = 0;
  1008.         symbolP = symbol_find_or_make(name);
  1009.         *p = c;
  1010.         S_SET_DESC(symbolP,temp);
  1011.     }
  1012.     demand_empty_rest_of_line();
  1013. } /* obj_elf_desc() */
  1014.  
  1015. void obj_read_begin_hook()
  1016. {
  1017.         return;
  1018. } /* obj_read_begin_hook() */
  1019.  
  1020. void obj_symbol_new_hook(symbolP)
  1021. symbolS *symbolP;
  1022. {
  1023.     elf_symbol_type *esym = (elf_symbol_type *)symbolP;
  1024.  
  1025.     /* there is an Elf_Internal_Sym and an Elf_External_Sym.  For */
  1026.     /* now, just zero them out. */
  1027.  
  1028.     bzero(&esym->internal_elf_sym,sizeof(Elf_Internal_Sym));
  1029.     bzero(&esym->native_elf_sym,sizeof(Elf_External_Sym));
  1030.     return;
  1031. } /* obj_symbol_new_hook() */
  1032.  
  1033. static void obj_elf_version()
  1034. {
  1035.     char *name;
  1036.     unsigned int c;
  1037.     char ch;
  1038.     char *p;
  1039.     int temp;
  1040.     symbolS *    symbolP;
  1041.     asection *seg = now_seg;
  1042.     subsegT subseg = now_subseg;
  1043.     Elf_Internal_Note i_note;
  1044.     Elf_External_Note e_note;
  1045.     asection *note_secp = (asection *)NULL;
  1046.     int i, len;
  1047.  
  1048.     SKIP_WHITESPACE();
  1049.     if (* input_line_pointer == '\"') {
  1050.       ++input_line_pointer; /* -> 1st char of string. */
  1051.       name = input_line_pointer;
  1052.  
  1053.       while ( is_a_char(c = next_char_of_string()) )
  1054.           ;
  1055.       c = *input_line_pointer;
  1056.       *input_line_pointer = '\0';
  1057.       *(input_line_pointer-1) = '\0';
  1058.       *input_line_pointer = c;
  1059.  
  1060.       /* create the .note section if this is the first version string */
  1061.  
  1062.       note_secp = bfd_get_section_by_name(stdoutput,".note");
  1063.       if ( note_secp == (asection *)NULL ) {
  1064.           note_secp = bfd_make_section_old_way(stdoutput,".note");
  1065.           bfd_set_section_flags(stdoutput,
  1066.                     note_secp,
  1067.                     SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS);
  1068.       }
  1069.  
  1070.       /* process the version string */
  1071.  
  1072.       subseg_new((char *)note_secp->name, 0);
  1073.       len = strlen(name);
  1074.  
  1075.       i_note.namesz    = ((len + 1) + 3) & ~3;    /* round this to word boundary    */
  1076.       i_note.descsz    = 0;            /* no description    */
  1077.       i_note.type    = NT_VERSION;
  1078.       p = frag_more(sizeof(e_note.namesz));
  1079.       md_number_to_chars(p, i_note.namesz, 4);
  1080.       p = frag_more(sizeof(e_note.descsz));
  1081.       md_number_to_chars(p, i_note.descsz, 4);
  1082.       p = frag_more(sizeof(e_note.type));
  1083.       md_number_to_chars(p, i_note.type,   4);
  1084.  
  1085.       for ( i = 0; i < len; i++ ) {
  1086.           ch = *(name + i);
  1087.           {
  1088.               FRAG_APPEND_1_CHAR( ch );
  1089.           }
  1090.       }
  1091.       frag_align(2,0);
  1092.  
  1093.       subseg_new((char *)seg->name,subseg);
  1094.     }
  1095.     else {
  1096.       as_bad( "Expected \"-ed string" );
  1097.     }
  1098.     demand_empty_rest_of_line();
  1099. }
  1100.  
  1101. static void
  1102. obj_elf_size ()
  1103. {
  1104.   char *name = input_line_pointer;
  1105.   char c = get_symbol_end ();
  1106.   char *p;
  1107.   expressionS exp;
  1108.   segT sec;
  1109.   symbolS *sym;
  1110.  
  1111.   p = input_line_pointer;
  1112.   *p = c;
  1113.   SKIP_WHITESPACE ();
  1114.   if (*input_line_pointer != ',')
  1115.     {
  1116.       *p = 0;
  1117.       as_bad ("expected comma after name `%s' in .size directive", name);
  1118.       *p = c;
  1119.       ignore_rest_of_line ();
  1120.       return;
  1121.     }
  1122.   input_line_pointer++;
  1123.   sec = expression (&exp);
  1124.   if (sec == absent_section)
  1125.     {
  1126.       as_bad ("missing expression in .size directive");
  1127.       exp.X_seg = absolute_section;
  1128.       exp.X_add_number = 0;
  1129.     }
  1130.   *p = 0;
  1131.   sym = symbol_find_or_make (name);
  1132.   *p = c;
  1133.   if (sec == absolute_section)
  1134.     S_SET_SIZE (sym, exp.X_add_number);
  1135.   else
  1136.     as_tsktsk (".size not yet supported, ignored");
  1137.   demand_empty_rest_of_line ();
  1138. }
  1139.  
  1140. static void
  1141. obj_elf_type ()
  1142. {
  1143.   char *name = input_line_pointer;
  1144.   char c = get_symbol_end ();
  1145.   char *p;
  1146.   int type;
  1147.   symbolS *sym;
  1148.  
  1149.   p = input_line_pointer;
  1150.   *p = c;
  1151.   SKIP_WHITESPACE ();
  1152.   if (*input_line_pointer != ',')
  1153.     {
  1154.       as_bad ("expected comma after name in .type directive");
  1155.     egress:
  1156.       ignore_rest_of_line ();
  1157.       return;
  1158.     }
  1159.   input_line_pointer++;
  1160.   SKIP_WHITESPACE ();
  1161.   if (*input_line_pointer != '#')
  1162.     {
  1163.       as_bad ("expected `#' after comma in .type directive");
  1164.       goto egress;
  1165.     }
  1166.   input_line_pointer++;
  1167.   if (!strncmp ("function", input_line_pointer, sizeof ("function") - 1))
  1168.     {
  1169.       type = BSF_FUNCTION;
  1170.       input_line_pointer += sizeof ("function") - 1;
  1171.     }
  1172.   else
  1173.     {
  1174.       as_bad ("unrecognized symbol type, ignored");
  1175.       goto egress;
  1176.     }
  1177.   demand_empty_rest_of_line ();
  1178.   *p = 0;
  1179.   sym = symbol_find_or_make (name);
  1180.   sym->bsym->flags = type;
  1181. }
  1182.  
  1183. static void
  1184. obj_elf_ident ()
  1185. {
  1186.   int xxx;
  1187.   char * string;
  1188.  
  1189.   string = demand_copy_C_string (&xxx);
  1190.   as_tsktsk (".ident not supported, ignoring");
  1191. }
  1192.